<template>
  <div class="app-container">
    <el-row class="wrapper pipeline">
      <el-col :span="24" class="warp-main">
        <div class="el-bar">
          <!--工具条-->
          <el-col :span="24" class="toolbar" style="padding-top:10px">
            <el-form :inline="true">
              <el-form-item>
                <el-button @click="pipelinePreAdd" icon="el-icon-plus" type="primary">新建集成流水线</el-button>
              </el-form-item>
              <el-form-item>
                <el-input v-model="queryKey" placeholder="请输入搜索关键字">
                </el-input>
              </el-form-item>
              <el-form-item>
                <el-button @click="pipelineQuery" icon="el-icon-search" type="primary">查询</el-button> 共{{total}}条记录
              </el-form-item>
            </el-form>
          </el-col>

          <!--数据列表-->
          <el-table v-loading="loadingTable" :data="queryData" highlight-current-row style="width: 100%;">
            <el-table-column prop="opration" width="50">
              <template slot-scope="scope">
                <el-tooltip class="item" effect="light" placement="top-start">
                  <div slot="content" v-if="scope.row.lastBuildResult === 'SUCCESS'">上次构建成功</div>
                  <div slot="content" v-else-if="scope.row.lastBuildResult === 'FAILURE'">上次构建失败</div>
                  <div slot="content" v-else-if="scope.row.lastBuildResult === 'NOT_BUILT'">未构建</div>
                  <div slot="content" v-else-if="scope.row.lastBuildResult === 'ABORTED'">构建中止</div>
                  <div slot="content" v-else-if="scope.row.lastBuildResult === 'BUILDING'">构建中...</div>
                  <i class='el-icon-loading' style="color: rgb(0, 0, 255); font-size: 20px;" v-if="scope.row.lastBuildResult === 'BUILDING'"></i>
                  <i class='el-icon-success' style="color: rgb(0, 0, 255); font-size: 20px;" v-if="scope.row.lastBuildResult === 'SUCCESS'"></i>
                  <i class='el-icon-error' style="color: rgb(255, 0, 0); font-size: 20px;" v-else-if="scope.row.lastBuildResult === 'FAILURE'"></i>
                  <i class='el-icon-info' style="color: rgb(96, 96, 96); font-size: 22px;" v-else-if="scope.row.lastBuildResult === 'NOT_BUILT'"></i>
                  <i class='el-icon-remove' style="color: rgb(96, 96, 96); font-size: 22px;" v-else-if="scope.row.lastBuildResult === 'ABORTED'"></i>
                </el-tooltip>
              </template>
            </el-table-column>
            <el-table-column prop="pipelineName" label="名称" sortable>
              <template slot-scope="scope">
                <el-tooltip content="编辑/查看流水线" placement="right">
                  <el-button @click="preUpdatePipeline(scope.$index, scope.row)" class="iconfont" type="text" size="small">{{scope.row.pipelineName}}</el-button>
                </el-tooltip>
              </template>
            </el-table-column>
            <el-table-column :formatter="simpleCloumnFormat1" :show-overflow-tooltip="true" prop="lastBuildTime" label="上次构建时间" sortable></el-table-column>
            <el-table-column :formatter="simpleCloumnFormat" :show-overflow-tooltip="true" prop="lastBuildDuration" label="上次持续时间(毫秒)" sortable></el-table-column>
            <el-table-column :formatter="simpleCloumnFormat1" :show-overflow-tooltip="true" prop="lastBuildNum" label="构建次数" sortable></el-table-column>
            <el-table-column :show-overflow-tooltip="true" prop="createUserName" label="创建者" sortable></el-table-column>
            <el-table-column :formatter="formatDate" :show-overflow-tooltip="true" prop="createTime" label="创建时间" sortable></el-table-column>
            <el-table-column label="操作" fixed="right" width="150">
              <template slot-scope="scope">
                <el-tooltip content="执行构建" placement="left">
                  <el-button @click="buildLogData.isRealBuildLog=true;pipelineLog(scope.$index, scope.row)" circle icon="el-icon-caret-right" type="primary" size="mini"></el-button>
                </el-tooltip>
                <el-tooltip content="查看构建日志" placement="top">
                  <el-button @click="buildLogData.isRealBuildLog=false;pipelineLog(scope.$index, scope.row)" circle icon="el-icon-document" type="primary" size="mini"></el-button>
                </el-tooltip>
                <el-tooltip content="删除流水线" placement="top">
                  <el-button circle icon="el-icon-delete" @click="deletePipeline(scope.$index, scope.row)" type="danger" size="mini"></el-button>
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
          <el-pagination style="margin-left:10px" background small layout="prev,pager,next" @current-change="handleCurrentPageChange" :total="total" :page-size="rowNum" :current-page="pageNum" :page-count="pages">
          </el-pagination>

          <!-- 流水线新增/编辑弹出框 -->
          <el-dialog :title="pipelineAdmData.title" width="950px" :visible.sync="pipelineAdmData.visible" :close-on-click-modal="true">
            <div v-loading="pipelineAdmData.loading" style="margin-left:10px;margin-right:8px;border-bottom: 1px solid #eaeaea;">
              <el-form style="font-size:22px;font-weight:bold;padding-left:10px;" :inline="true">
                <el-form-item>
                  <el-button @click="savePipeline" icon="el-icon-check" type="primary">保存</el-button>
                  <el-button @click="cancelPipeline" icon="el-icon-back" type="primary">取消</el-button>
                </el-form-item>
              </el-form>
            </div>
            <div style="margin-top:5px;margin-left:10px;margin-right:8px;border-bottom: 1px solid #eaeaea;">
              <el-form :inline="true" style="font-size:22px;font-weight:bold;padding-left:10px;">
                <el-form-item required label="流水线名称 ">
                  <el-input v-model="pipelineAdmData.form.pipelineName" style="width:150px">
                  </el-input>
                </el-form-item>
                <el-form-item required label="构建记录保持天数 ">
                  <el-input-number v-model="pipelineAdmData.form.keepBuildDay" :min="2" :max="10" label="构建记录保持天数"></el-input-number>
                </el-form-item>
                <el-form-item required label="构建记录保持份数 ">
                  <el-input-number v-model="pipelineAdmData.form.keepBuildNumber" :min="2" :max="10" label="构建记录保持份数"></el-input-number>
                </el-form-item>
              </el-form>
              <el-form style="font-size:22px;font-weight:bold;padding-left:19px;" :inline="true">
                <el-form-item label="流水线参数">
                  <el-button @click="addPara" icon="el-icon-plus" type="text">添加参数</el-button>
                </el-form-item>
              </el-form>
              <el-form v-for="(item, index) in pipelineAdmData.form.pps" v-bind:key="index" :inline="true" style="margin-left:85px;font-size:22px;font-weight:bold;padding-left:10px;">
                <el-form-item required label="参数名 ">
                  <el-input v-model="item.paraName" style="width:200px">
                  </el-input>
                </el-form-item>
                <el-form-item required label="默认值 ">
                  <el-input v-model="item.paraDefaultValue" style="width:100px">
                  </el-input>
                </el-form-item>
                <el-form-item>
                  <el-button icon="el-icon-minus" style="color:#F00" @click.prevent="removePara(item)" type="text">删除参数</el-button>
                </el-form-item>
              </el-form>
            </div>
            <div style="margin-top:5px;margin-right:8px;">
              <el-form style="font-size:22px;font-weight:bold;" :inline="true">
                <el-form-item label="">
                  <el-button @click="addStage" icon="el-icon-plus" type="text">添加阶段</el-button>
                </el-form-item>
              </el-form>
              <div v-if="pipelineAdmData.form.pss.length>0" style="padding:1px;border: 0px solid #eaeaea;width:100%;overflow-y:auto;">
                <el-collapse style="margin-left:20px;width:96%" v-model="pipelineAdmData.stageActiveNames">
                  <el-collapse-item v-for="(item, index) in pipelineAdmData.form.pss" v-bind:key="index" :name="''+index">
                    <template slot="title">
                      <div class="line"></div>
                      <span class="Title">阶段{{index+1}}#
                        <el-button style="color:#F00;width:5px;padding:0px 0px !important" type="text">*</el-button>
                        <el-input placeholder="请输入阶段名称" v-model="item.stageName" style="width:150px">
                        </el-input>
                        <el-button icon="el-icon-minus" style="color:#F00" @click.prevent="removeStage(item)" type="text">删除阶段</el-button>
                        <el-dropdown @command="addJob">
                          <span class="el-dropdown-link">
                            <el-button icon="el-icon-plus" type="text">添加任务</el-button>
                          </span>
                          <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item :command="{stage:item,jobType:1}">svn获取代码</el-dropdown-item>
                            <el-dropdown-item :command="{stage:item,jobType:2}">maven构建</el-dropdown-item>
                            <el-dropdown-item :command="{stage:item,jobType:3}">nodejs构建</el-dropdown-item>
                            <el-dropdown-item :command="{stage:item,jobType:4}">docker镜像构建</el-dropdown-item>
                            <el-dropdown-item :command="{stage:item,jobType:99}">执行shell</el-dropdown-item>
                          </el-dropdown-menu>
                        </el-dropdown>
                      </span>
                    </template>

                    <!-- 任务折叠 -->
                    <el-collapse v-if="item.pjs.length>0" style="margin-left:20px;width:96%">
                      <el-collapse-item v-for="(pj, index1) in item.pjs" v-bind:key="index1" :name="''+index1">
                        <template slot="title">
                          <div class="line"></div>
                          <span v-if="pj.jobType==1" class="Title">任务{{index1+1}}#类型:获取代码</span>
                          <span v-if="pj.jobType==2" class="Title">任务{{index1+1}}#类型:maven构建</span>
                          <span v-if="pj.jobType==3" class="Title">任务{{index1+1}}#类型:nodejs构建</span>
                          <span v-if="pj.jobType==4" class="Title">任务{{index1+1}}#类型:docker镜像构建</span>
                          <span v-if="pj.jobType==99" class="Title">任务{{index1+1}}#类型:执行shell</span>
                          <el-button icon="el-icon-minus" style="color:#F00" @click.prevent="removeJob(item.pjs,pj)" type="text">删除任务</el-button>
                        </template>

                        <el-form v-if="pj.jobType==1" :inline="true" style="margin-left:14px">
                          <el-form-item required label="任务名称 ">
                            <el-input v-model="pj.jobName" style="width:200px">
                            </el-input>
                          </el-form-item>
                          <el-form-item label="构建目录 ">
                            <el-input v-model="pj.buildDir" style="width:200px" />
                          </el-form-item>
                          <el-form-item required label="代码源 ">
                            <el-select v-model="pj.codeSource" placeholder="请选择">
                              <el-option v-for="ele in pipelineAdmData.codeSources" :key="ele.id" :label="ele.codeName" :value="ele.id">
                              </el-option>
                            </el-select>
                          </el-form-item>
                        </el-form>
                        <el-form v-if="pj.jobType==2" :inline="true" style="margin-left:14px">
                          <el-form-item required label="任务名称 ">
                            <el-input v-model="pj.jobName" style="width:200px">
                            </el-input>
                          </el-form-item>
                          <el-form-item label="构建目录 ">
                            <el-input v-model="pj.buildDir" style="width:200px" />
                          </el-form-item>
                          <el-form-item required label="jdk版本 ">
                            <el-select @change="jdkSelectChange(pj,pj.jdkVersion)" v-model="pj.jdkVersion" placeholder="请选择">
                              <el-option v-for="ele in pipelineAdmData.jdkInfo" :key="ele.jdkVersion" :label="ele.jdkVersion" :value="ele.jdkVersion">
                              </el-option>
                            </el-select>
                          </el-form-item>
                          <el-form-item required label="构建命令 ">
                            <el-input v-model="pj.mavenShell" :rows="4" style="width:467px" type="textarea" />
                          </el-form-item>
                        </el-form>
                        <el-form v-if="pj.jobType==3" :inline="true" style="margin-left:14px">
                          <el-form-item required label="任务名称 ">
                            <el-input v-model="pj.jobName" style="width:200px">
                            </el-input>
                          </el-form-item>
                          <el-form-item label="构建目录 ">
                            <el-input v-model="pj.buildDir" style="width:200px" />
                          </el-form-item>
                          <el-form-item required label="构建命令 ">
                            <el-input v-model="pj.nodejsShell" :rows="4" style="width:467px" type="textarea" />
                          </el-form-item>
                        </el-form>
                        <el-form v-if="pj.jobType==4" :inline="true" style="margin-left:14px">
                          <el-form-item required label="任务名称 ">
                            <el-input v-model="pj.jobName" style="width:200px">
                            </el-input>
                          </el-form-item>
                          <el-form-item label="构建目录 ">
                            <el-input v-model="pj.buildDir" style="width:200px" />
                          </el-form-item>
                          <el-form-item required label="镜像名称 ">
                            <el-input v-model="pj.dockerImageName" style="width:200px">
                            </el-input>
                          </el-form-item>
                          <el-form-item required label="版本策略 ">
                            <el-select style="width:200px" v-model="pj.dockerVersionStrategy" placeholder="请选择">
                              <el-option label="时间戳" :value="1" />
                              <el-option label="参数传递" :value="2" />
                            </el-select>
                          </el-form-item>
                          <el-form-item required v-if="pj.dockerVersionStrategy==2" label="传参名称 ">
                            <el-select style="width:200px" v-model="pj.dockerImageVersionPara" placeholder="请选择">
                              <el-option v-for="ele in pipelineAdmData.form.pps" :key="ele.paraName" :label="ele.paraName" :value="ele.paraName">
                              </el-option>
                            </el-select>
                          </el-form-item>
                        </el-form>
                        <el-form v-if="pj.jobType==99" :inline="true" style="margin-left:14px">
                          <el-form-item required label="任务名称 ">
                            <el-input v-model="pj.jobName" style="width:200px" />
                          </el-form-item>
                          <el-form-item label="构建目录 ">
                            <el-input v-model="pj.buildDir" style="width:200px" />
                          </el-form-item>
                          <el-form-item required label="shell脚本 ">
                            <el-input v-model="pj.shell" :rows="15" style="width:700px;" type="textarea"></el-input>
                          </el-form-item>
                        </el-form>
                      </el-collapse-item>
                    </el-collapse>
                    <!-- 任务折叠 -->
                  </el-collapse-item>
                </el-collapse>
              </div>
            </div>
          </el-dialog>

          <!-- 构建日志弹出框 -->
          <el-dialog :title="buildLogData.title" width="950px" :visible.sync="buildLogData.visible" :close-on-click-modal="true">
            <div v-if="buildLogData.paraData.length>0" style="margin-left:10px;margin-right:8px;border-bottom: 1px solid #eaeaea;">
              <el-form style="font-size:22px;font-weight:bold;padding-left:10px;" :inline="true" v-for="(item, index) in buildLogData.paraData" v-bind:key="item.id">
                <el-form-item label="参数名:">
                  <el-input v-model="item.paraName" :disabled="true">
                  </el-input>
                </el-form-item>
                <el-form-item label="默认值:">
                  <el-input v-model="item.paraDefaultValue" :disabled="true">
                  </el-input>
                </el-form-item>
                <el-form-item required label="真实值:">
                  <el-input v-model="item.paraValue">
                  </el-input>
                </el-form-item>
                <el-form-item v-if="index==(buildLogData.paraData.length-1)">
                  <el-button :disabled="buildLogData.buildBtnWithParaDisable" @click="pipelineBuildByPara" icon="el-icon-caret-right" type="primary">执行构建</el-button>
                </el-form-item>
              </el-form>
            </div>

            <el-row class="wrapper warehouse" style="height:520px;">
              <!-- 左边的步骤条.start -->
              <el-col :span="6">
                <el-tree default-expand-all highlight-current ref="refTree" node-key="id" :data="buildLogData.treeData" :props="buildLogData.treeProps" @node-click="handleNodeClick"></el-tree>
              </el-col>
              <!-- 左边的步骤条.end -->
              <!-- 表单 -->
              <el-col :span="18" style="border-left:1px solid #eaeaea;padding:0 10px;">
                <p style="width:680px;">
                  <el-tooltip class="item" effect="light" placement="top-start">
                    <div slot="content" v-if="buildLogData.buildLogStatus === 'NOT_BUILT'">待执行构建</div>
                    <i v-if="buildLogData.buildLogStatus === 'NOT_BUILT'" class='el-icon-info' style="color: rgb(96, 96, 96); font-size: 22px;"></i>
                  </el-tooltip>
                  <el-tooltip class="item" effect="light" placement="top-start">
                    <div slot="content" v-if="buildLogData.buildLogStatus === 'SUCCESS'">构建成功</div>
                    <i v-if="buildLogData.buildLogStatus === 'SUCCESS'" class='el-icon-success' style="color: rgb(0, 0, 255); font-size: 22px;"></i>
                  </el-tooltip>
                  <el-tooltip class="item" effect="light" placement="top-start">
                    <div slot="content" v-if="buildLogData.buildLogStatus === 'FAILURE'">构建失败</div>
                    <i v-if="buildLogData.buildLogStatus === 'FAILURE'" class='el-icon-error' style="color: rgb(255, 0, 0); font-size: 22px;"></i>
                  </el-tooltip>
                  <el-tooltip class="item" effect="light" placement="top-start">
                    <div slot="content" v-if="buildLogData.buildLogStatus === 'ABORTED'">构建中止</div>
                    <i v-if="buildLogData.buildLogStatus === 'ABORTED'" class='el-icon-remove' style="color: rgb(96, 96, 96); font-size: 22px;"></i>
                  </el-tooltip>
                  <el-tooltip class="item" effect="light" placement="top-start">
                    <div slot="content" v-if="buildLogData.buildLogStatus === 'BUILDING'">构建中...</div>
                    <i v-if="buildLogData.buildLogStatus === 'BUILDING'" class='el-icon-loading' style="color: rgb(0, 0, 255); font-size: 22px;"></i>
                  </el-tooltip>
                  <el-tooltip class="item" effect="light" placement="top-start">
                    <div slot="content" v-if="buildLogData.buildLogStatus === 'LOADING'">加载中...</div>
                    <i v-if="buildLogData.buildLogStatus === 'LOADING'" class='el-icon-loading' style="color: rgb(0, 0, 255); font-size: 22px;"></i>
                  </el-tooltip>
                  <i class="iconfont icon-users" style="font-size:22px;font-weight:bold;padding:5px">控制台输出({{buildLogData.buildLogDetail}})</i>
                </p>
                <el-form :inline="true" style="margin-top:10px">
                  <el-form-item label="">
                    <div v-html="buildLogData.logContainer" style="padding:10px;line-height:18px;height:480px;width:680px;overflow:auto;background:#000;color:#FFF">
                    </div>
                  </el-form-item>
                </el-form>
              </el-col>
            </el-row>
          </el-dialog>
        </div>
      </el-col>
    </el-row>
  </div>
</template>
<script>
import { Notification } from 'element-ui';
export default {
  data() {
    return {
      //查询关键词
      queryKey: '',
      //分页信息
      pages: 0,  //一共有多少页
      pageNum: 1,//当前查询的页码
      rowNum: 10,//每页显示的行数
      total: 0,//总数
      //查询结果信息
      queryData: [],
      loadingTable: false,//table 遮罩
      //构建日志信息
      buildLogData: {
        //弹出框
        title: '构建日志',
        visible: false,
        buildLogDetail: '#',
        buildLogStatus: 'BUILDING',
        isRealBuildLog: true,//是否实时构建日志
        currentBuildNum: 0,//当前构建次数
        currentRow: {},//当前行
        buildBtnWithParaDisable: false,
        //log tree
        treeData: [
        ],
        treeProps: {
          children: 'children',
          label: 'label'
        },
        //log container
        logContainer: "加载中...",
        paraData: [],
        interval: -1,
        timeout: -1,
      },
      //流水线管理数据
      pipelineAdmData: {
        title: '新增流水线',
        visible: false,
        stageActiveNames: "",
        jobActiveNames: "",
        codeSources: [],
        jdkInfo: [],
        loading: false,//table 遮罩
        form: {
          id: "",
          keepBuildDay: 2,
          keepBuildNumber: 2,
          pipelineName: "",
          pipelineType: 1,
          pps: [],
          pss: []
        }
      }
    }
  },
  methods: {
    //jdk参数选择处理
    jdkSelectChange: function(pj, jdkVersion) {
      this.pipelineAdmData.jdkInfo.forEach(function(item) {
        if (item.jdkVersion == jdkVersion) {
          pj.jdkPath = item.jdkPath;
          return;
        }
      });
    },
    //添加参数
    addPara() {
      let para = { paraDefaultValue: "", paraName: "", paraValue: "", remark: "" };
      this.pipelineAdmData.form.pps.push(para);
    },
    //移除参数
    removePara(item) {
      var index = this.pipelineAdmData.form.pps.indexOf(item)
      if (index !== -1) {
        this.pipelineAdmData.form.pps.splice(index, 1)
      }
    },
    //添加阶段
    addStage() {
      let para = { stageName: "", pjs: [] };
      this.pipelineAdmData.form.pss.push(para);
    },
    //移除阶段
    removeStage(item) {
      var index = this.pipelineAdmData.form.pss.indexOf(item)
      if (index !== -1) {
        this.pipelineAdmData.form.pss.splice(index, 1)
      }
    },
    //添加任务
    addJob(obj) {
      let para = { buildDir: "", codeSource: "", dockerImageName: "", dockerImageVersionPara: "", dockerVersionStrategy: 1, jdkPath: "", jdkVersion: "", jobName: "", jobType: obj.jobType, mavenShell: "", nodejsShell: "", shell: "" };
      obj.stage.pjs.push(para);
    },
    //删除任务
    removeJob(pjs, pj) {
      var index = pjs.indexOf(pj)
      if (index !== -1) {
        pjs.splice(index, 1)
      }
    },
    //代码库查询
    codeSourcesQuery() {
      let url = this.projectConfig.URL_API_CI_CODE_SOURCE_ALL;
      let teamId = this.userBaseInfo.getCurrentSelectedTeam();
      url += "?teamId=" + teamId;
      this.httpClient.httpClientget(url).then((response) => {
        // 遮罩结束
        this.pipelineAdmData.codeSources = response.data;
      }).catch(error => {
        // 遮罩结束
      });
    },
    //jdk信息查询
    jdkInfoQuery() {
      let url = this.projectConfig.URL_API_CI_PIPELINE_CONFIG_JDK;
      this.httpClient.httpClientget(url).then((response) => {
        // 遮罩结束
        this.pipelineAdmData.jdkInfo = response.data;
      }).catch(error => {
        // 遮罩结束
      });
    },
    //查询
    pipelineQuery() {
      this.queryData = [];
      let url = this.projectConfig.URL_API_CI_PIPELINE;
      let namespace = this.userBaseInfo.getCurrentSelectedNamespace();
      url += "?key=" + this.queryKey
        + "&namespace=" + namespace
        + "&pageNum=" + this.pageNum
        + "&rowNum=" + this.rowNum;
      this.loadingTable = true;
      this.httpClient.httpClientget(url).then((response) => {
        // 遮罩结束
        this.loadingTable = false;
        this.queryData = response.data.list;
        this.pages = response.data.pages;
        this.total = response.data.total;
      }).catch(error => {
        // 遮罩结束
        this.loadingTable = false;
      });
    },
    //查询(单行记录)
    pipelineRowQuery(id) {
      let url = this.projectConfig.URL_API_CI_PIPELINE_ROW;
      url = this.httpClient.urlParmHandle(url, [id]);
      this.httpClient.httpClientget(url).then((response) => {
        // 遮罩结束
        let d = response.data;
        this.queryData.forEach(function(item) {
          if (item.id == d.id) {
            item.id = d.id;
            item.pipelineName = d.pipelineName;
            item.pipelineNameEn = d.pipelineNameEn;
            item.createTime = d.createTime;
            item.remark = d.remark;
            item.lastBuildResult = d.lastBuildResult;
            item.lastBuildDuration = d.lastBuildDuration;
            item.lastBuildNum = d.lastBuildNum;
            item.lastBuildTime = d.lastBuildTime;
            return;
          }
        });
      }).catch(error => {
        // 遮罩结束
      });
    },
    //日志查询
    pipelineLog(index, row) {
      this.buildLogData.currentBuildNum = row.lastBuildNum;
      this.buildLogData.currentRow = row;
      if (this.buildLogData.isRealBuildLog) {
        if (this.buildLogData.interval != -1) {
          this.$notify({
            title: '温馨提醒',
            message: '有流水线构建中,需要等待该流水线执行完成后才可以继续执行!',
            type: 'warning'
          });
          return;
        }
        //实时构建日志
        this.buildLogData.paraData = [];
        //获取参数 start
        let urlPara = this.projectConfig.URL_API_CI_PIPELINE_CONFIG_PARA;
        urlPara = this.httpClient.urlParmHandle(urlPara, [row.id]);
        this.httpClient.httpClientget(urlPara).then((response) => {
          // 遮罩结束
          this.buildLogData.paraData = response.data;
          this.buildLogData.visible = true;
          if (this.buildLogData.paraData.length == 0) {
            //前置处理start
            this.buildLogData.title = '实时构建日志(#流水线:' + row.pipelineName + ')';
            this.buildLogData.treeData = [];
            this.buildLogData.logContainer = "构建初始化中...";
            this.buildLogData.buildLogStatus = "BUILDING";
            this.buildLogData.buildLogDetail = "";
            //前置处理end
            //没有参数直接构建
            this.pipelineBuild(row.id, row.pipelineNameEn);
          } else {
            //前置处理start
            this.buildLogData.title = '实时构建日志(#流水线:' + row.pipelineName + ')';
            this.buildLogData.treeData = [];
            this.buildLogData.logContainer = "===待执行构建===";
            this.buildLogData.buildLogStatus = "NOT_BUILT";
            this.buildLogData.buildLogDetail = "";
            //前置处理end
          }
        }).catch(error => {
          // 遮罩结束
        });
        //获取参数 end
      } else {
        //历史构建日志
        if (row != undefined && row.lastBuildResult == 'NOT_BUILT') {
          this.$notify({
            title: '温馨提醒',
            message: '请先构建该条流水线!',
            type: 'warning'
          });
          return;
        }

        this.buildLogData.paraData = [];
        this.buildLogData.visible = true;

        let url = this.projectConfig.URL_API_CI_PIPELINE_BUILD_LOG_HISTORY;
        url = this.httpClient.urlParmHandle(url, [row.id, row.pipelineNameEn, this.buildLogData.currentBuildNum]);
        //前置处理start
        this.buildLogData.title = '构建日志(#流水线:' + row.pipelineName + ')';
        this.buildLogData.treeData = [];
        this.buildLogData.logContainer = "加载中...";
        this.buildLogData.buildLogStatus = "LOADING";
        this.buildLogData.buildLogDetail = "";
        //前置处理end
        this.httpClient.httpClientget(url).then((response) => {
          //历史日志
          let responseData = response.data;
          let treeDatas = [];
          let i = 1;
          let _this = this;
          responseData.forEach(function(item) {
            let result = item.result;
            let timeShow = item.timeShow;
            let stages = item.pipelineConsoleOutputText;
            let treeChildren = [];
            /////////////////////
            //第1个选中
            if (i == 1) {
              _this.buildLogData.logContainer = item.consoleOutputText;
              _this.buildLogData.buildLogStatus = result;
              _this.buildLogData.buildLogDetail = item.displayName;
            }
            /////////////////////
            let td = {
              id: i++,
              level: 1,
              result: result,
              displayName: item.displayName,
              label: item.displayName + ' ' + timeShow + ' ' + result,
              consoleOutputText: item.consoleOutputText,
              children: treeChildren
            }
            stages.forEach(function(ele) {
              let tcd = {
                id: i++,
                level: 2,
                result: ele.result,
                displayName: item.displayName,
                label: ele.stageName + ' #' + ele.result,
                consoleOutputText: ele.consoleOutputText,
                children: []
              }
              treeChildren.push(tcd);
            });
            treeDatas.push(td);
          });
          this.buildLogData.treeData = treeDatas;
        }).catch(error => {
          // 遮罩结束
        });
      }
    },
    //流水线构建(带参数)
    pipelineBuildByPara() {
      this.buildLogData.buildBtnWithParaDisable = true;
      let validate = true;
      let _this = this;
      this.buildLogData.paraData.forEach(function(item) {
        if (item.paraValue == '') {
          _this.$notify({
            title: '温馨提醒',
            message: '流水线全局参数真实值不能为空!',
            type: 'warning'
          });
          validate = false;
          return;
        }
      });
      if (validate) {
        this.buildLogData.treeData = [];
        this.buildLogData.logContainer = "构建初始化中...";
        this.buildLogData.buildLogStatus = "BUILDING";
        this.buildLogData.buildLogDetail = "";
        this.pipelineBuild(this.buildLogData.currentRow.id, this.buildLogData.currentRow.pipelineNameEn);
      }
    },
    //流水线构建(不带参数)
    pipelineBuild(id, pipelineNameEn) {
      this.buildLogData.currentRow.lastBuildResult = "BUILDING";
      let url = this.projectConfig.URL_API_CI_PIPELINE_BUILD;
      url = this.httpClient.urlParmHandle(url, [id, pipelineNameEn]);
      this.httpClient.httpClientPost(url, this.buildLogData.paraData).then((response) => {
        let buildNum = response.data;
        let _this = this;
        this.buildLogData.timeout = setTimeout(function() {
          let j = 1;
          _this.buildLogData.interval = setInterval(function() {
            let flag = _this.stopInterval(_this);
            if (flag) {
              return;
            }
            ////////////异步执行查询/////////////
            let url = _this.projectConfig.URL_API_CI_PIPELINE_BUILD_LOG_CURRENT;
            url = _this.httpClient.urlParmHandle(url, [id, pipelineNameEn, buildNum]);
            _this.httpClient.httpClientget(url).then((response) => {
              if (response.data == 'no log record') {
                //还没有执行日志
                return;
              }
              _this.buildLogData.buildLogStatus = response.data.result;
              if (_this.buildLogData.buildLogStatus == 'BUILDING') {
                response.data.consoleOutputText = response.data.consoleOutputText + "加载中..."
              }
              //实时日志
              let responseData = [];
              responseData.push(response.data);
              let treeDatas = [];
              let i = 1;
              responseData.forEach(function(item) {
                let result = item.result;
                let timeShow = item.timeShow;
                let stages = item.pipelineConsoleOutputText;
                let treeChildren = [];
                /////////////////////
                //第1个选中
                if (i == 1) {
                  _this.buildLogData.logContainer = item.consoleOutputText;
                  _this.buildLogData.buildLogStatus = result;
                  _this.buildLogData.buildLogDetail = item.displayName;
                }
                /////////////////////
                let td = {
                  id: i++,
                  level: 1,
                  result: result,
                  displayName: item.displayName,
                  label: item.displayName + ' ' + timeShow + ' ' + result,
                  consoleOutputText: item.consoleOutputText,
                  children: treeChildren
                }
                stages.forEach(function(ele) {
                  let tcd = {
                    id: i++,
                    level: 2,
                    result: ele.result,
                    displayName: item.displayName,
                    label: ele.stageName + ' #' + ele.result,
                    consoleOutputText: ele.consoleOutputText,
                    children: []
                  }
                  treeChildren.push(tcd);
                });
                treeDatas.push(td);
              });
              _this.buildLogData.treeData = treeDatas;
            }).catch(error => {
              // 遮罩结束
            });
            ////////////异步执行查询/////////////
          }, 3000);//1s定时执行
        }, 5000);//延迟5s执行
      });
    },
    //停止定时任务
    stopInterval(obj) {
      if (obj.buildLogData.buildLogStatus != 'BUILDING') {
        //构建结束,结束定时器
        if (obj.buildLogData.interval > -1) {
          clearInterval(obj.buildLogData.interval);
          obj.buildLogData.interval = -1;
          obj.pipelineRowQuery(obj.buildLogData.currentRow.id);
          this.buildLogData.buildBtnWithParaDisable = false;

          if (obj.buildLogData.timeout) {
            clearTimeout(obj.buildLogData.timeout);
            obj.buildLogData.timeout = -1;
          }
          return true;
        }
      }
      return false;
    },
    //数节点点击
    handleNodeClick(data) {
      this.buildLogData.logContainer = data.consoleOutputText;
      this.buildLogData.buildLogStatus = data.result;
      this.buildLogData.buildLogDetail = data.displayName;
    },
    //新增流水线前处理
    pipelinePreAdd() {
      this.pipelineAdmData.title = "新增流水线";
      this.pipelineAdmData.form = {
        id: "",
        keepBuildDay: 2,
        keepBuildNumber: 2,
        pipelineName: "",
        pipelineType: 1,
        pps: [],
        pss: []
      };
      this.pipelineAdmData.visible = true;
    },
    //更新流水线前处理
    preUpdatePipeline: function(index, row) {
      let url = this.projectConfig.URL_API_CI_PIPELINE_DETAIL;
      url = this.httpClient.urlParmHandle(url, [row.id]);
      this.httpClient.httpClientget(url).then((response) => {
        // 遮罩结束
        let d = response.data;
        this.pipelineAdmData.form = d;
        this.pipelineAdmData.title = "查看/修改流水线";
        this.pipelineAdmData.visible = true;
      }).catch(error => {
        // 遮罩结束
      });
    },
    //取消流水线操作
    cancelPipeline() {
      this.pipelineAdmData.visible = false;
    },
    //新增/修改流水线保存
    savePipeline() {
      //验证代码 start
      if (this.pipelineAdmData.form.pipelineName == '') {
        this.$message({ message: '流水线名称不能为空!', type: 'warning' });
        return;
      }
      let flag = false;
      let _this = this;
      this.pipelineAdmData.form.pps.forEach(function(item) {
        if (item.paraName == '') {
          _this.$message({ message: '参数名称不能为空!', type: 'warning' });
          flag = true;
          return;
        }
        if (item.paraDefaultValue == '') {
          _this.$message({ message: '参数默认值不能为空!', type: 'warning' });
          flag = true;
          return;
        }
      });
      if (flag) return;
      if (this.pipelineAdmData.form.pss.length == 0) {
        this.$message({ message: '流水线至少需要一个阶段!', type: 'warning' });
        return;
      }
      this.pipelineAdmData.form.pss.forEach(function(item) {
        if (item.stageName == '') {
          _this.$message({ message: '阶段名称不能为空!', type: 'warning' });
          flag = true;
          return;
        }
        if (item.pjs.length == 0) {
          _this.$message({ message: '阶段至少需要添加一个任务!', type: 'warning' });
          flag = true;
          return;
        }
        item.pjs.forEach(function(pj) {
          if (pj.jobName == '') {
            _this.$message({ message: '任务名称不能为空!', type: 'warning' });
            flag = true;
            return;
          }
          if (pj.jobType == 1) {
            if (pj.codeSource == '') {
              _this.$message({ message: '代码源不能为空!', type: 'warning' });
              flag = true;
              return;
            }
          }
          if (pj.jobType == 2) {
            if (pj.jdkVersion == '') {
              _this.$message({ message: 'jdk版本不能为空!', type: 'warning' });
              flag = true;
              return;
            }
            if (pj.mavenShell == '') {
              _this.$message({ message: 'maven构建命令不能为空!', type: 'warning' });
              flag = true;
              return;
            }
          }
          if (pj.jobType == 3) {
            if (pj.nodejsShell == '') {
              _this.$message({ message: 'nodejs构建命令不能为空!', type: 'warning' });
              flag = true;
              return;
            }
          }
          if (pj.jobType == 4) {
            if (pj.dockerImageName == '') {
              _this.$message({ message: '镜像名称不能为空!', type: 'warning' });
              flag = true;
              return;
            }
            if (pj.dockerVersionStrategy == 2) {
              if (pj.dockerImageVersionPara == '') {
                _this.$message({ message: '镜像版本参数名称不能为空!', type: 'warning' });
                flag = true;
                return;
              }
              if (_this.pipelineAdmData.form.pps.length == 0) {
                _this.$message({ message: '镜像版本参数名称[' + pj.dockerImageVersionPara + ']不存在,请添加该流水线参数!', type: 'warning' });
                flag = true;
                return;
              }
              let hasPara = false;
              _this.pipelineAdmData.form.pps.forEach(function(para) {
                if (para.paraName == pj.dockerImageVersionPara) {
                  hasPara = true;
                  return;
                }
              });
              if (!hasPara) {
                _this.$message({ message: '镜像版本参数名称[' + pj.dockerImageVersionPara + ']不存在,请添加该流水线参数!', type: 'warning' });
                flag = true;
                return;
              }
            }
          }
          if (pj.jobType == 99) {
            if (pj.shell == '') {
              _this.$message({ message: 'shell脚本不能为空!', type: 'warning' });
              flag = true;
              return;
            }
          }
        });
      });
      if (flag) return;
      //验证代码 end
      this.pipelineAdmData.loading = true;
      if (this.pipelineAdmData.form.id == '') {
        //新增
        //保存
        this.pipelineAdmData.form.createUser = this.userBaseInfo.getUserId();
        this.pipelineAdmData.form.updateUser = this.userBaseInfo.getUserId();
        this.pipelineAdmData.form.namespace = this.userBaseInfo.getCurrentSelectedNamespace();
        this.pipelineAdmData.form.pipelineType = 1;
        let url = this.projectConfig.URL_API_CI_PIPELINE;
        this.httpClient.httpClientPost(url, this.pipelineAdmData.form).then((response) => {
          if (response != undefined && response.data != undefined && response.data == '1') {
            //新增成功
            this.pipelineAdmData.loading = false;
            this.pipelineAdmData.visible = false;
            this.pipelineQuery();
          } else {
            //新增失败
            this.pipelineAdmData.loading = false;
          }
        }).catch(error => {
          // 遮罩结束
          this.pipelineAdmData.loading = false;
          this.pipelineAdmData.visible = false;
        });
      } else {
        //修改
        this.pipelineAdmData.form.updateUser = this.userBaseInfo.getUserId();
        this.pipelineAdmData.form.namespace = this.userBaseInfo.getCurrentSelectedNamespace();
        this.pipelineAdmData.form.pipelineType = 1;
        let url = this.projectConfig.URL_API_CI_PIPELINE;
        this.httpClient.httpClientPatch(url, this.pipelineAdmData.form).then((response) => {
          if (response != undefined && response.data != undefined && response.data == '1') {
            //修改成功
            this.pipelineAdmData.loading = false;
            this.pipelineAdmData.visible = false;
            this.pipelineQuery();
          } else {
            //修改失败
            this.pipelineAdmData.loading = false;
          }
        }).catch(error => {
          // 遮罩结束
          this.pipelineAdmData.loading = false;
          this.pipelineAdmData.visible = false;
        });
      }
    },
    // 删除流水线
    deletePipeline: function(index, row) {
      this.$confirm("此操作将永久删除此集成流水线, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        let url = this.projectConfig.URL_API_CI_PIPELINE;
        url += "?id=" + row.id + "&pipelineNameEn=" + row.pipelineNameEn;
        this.httpClient.httpClientDelete(url).then((response) => {
          this.pipelineQuery();
        });
      }).catch(() => {
        this.$message({
          type: "info",
          message: "已取消操作"
        });
      });
    },
    //分页点击事件
    handleCurrentPageChange(val) {
      this.pageNum = val;
      //查询
      this.pipelineQuery();
    },
    formatDate: function(row, column, cellValue) {
      if (cellValue == '' || cellValue == undefined) {
        return '';
      }
      return cellValue.split('.')[0];
    },
    simpleCloumnFormat: function(row, column, cellValue) {
      if (row.lastBuildResult == 'NOT_BUILT') {
        return '未构建';
      } if (row.lastBuildResult == 'BUILDING') {
        return '构建中...';
      }
      return cellValue;
    },
    simpleCloumnFormat1: function(row, column, cellValue) {
      if (row.lastBuildResult == 'NOT_BUILT') {
        return '未构建';
      }
      return cellValue;
    }
  },
  mounted: function() {
    this.pipelineQuery();
    this.codeSourcesQuery();
    this.jdkInfoQuery();
  },
  computed: {
    getCurrentNamespace() {
      return this.$store.getters.namespace;
    }
  },
  watch: {
    getCurrentNamespace(val) {
      this.pipelineQuery();
    }
  }
}
</script>
<style>
.pipeline .el-table tr {
  text-align: center;
}

.pipeline .el-time {
  border: 1px solid;
  border-radius: 4px;
}

.pipeline .el-width {
  width: 400px;
}

.pipeline .el-bar {
  padding-bottom: 50px;
}

.pipeline .el-bar .nbd {
  border-bottom: none;
}

.pipeline .el-dialog__header {
  padding: 15px 10px 10px;
  border-bottom: 1px solid #ccc;
}

.pipeline .el-dialog__body {
  padding: 10px 10px;
  color: #5a5e66;
  line-height: 24px;
  font-size: 14px;
}

.pipeline el-icon-search {
  border: 1px solid #eaeaea;
  border-radius: 4px;
}

.pipeline .search .el-input {
  border: 1px solid #eaeaea;
}

.pipeline .el-date-editor--datetimerange {
  border: 1px solid #eaeaea;
  border-radius: 4px;
}

.pipeline .el-table .cell {
  padding: 0;
}

.pipeline .line {
  margin-top: 13px;
  float: left;
  width: 3px;
  height: 17px;
  margin-right: 10px;
  border-left: 3px solid #00a1ea;
}

.pipeline .Title {
  font-size: 15px;
}

.el-input-number {
  position: relative;
  display: inline-block;
  width: 180px;
  line-height: 35px;
}
</style>